<script setup lang="ts">
import type { Role } from '#/api/core/role';
import type { RolePermissionTreeNode } from '#/api/core/permission';

import { computed, ref, watch } from 'vue';

import { Button, Checkbox, Input, message, Modal, Space, Spin, Table } from 'ant-design-vue';
import type { TableColumnsType } from 'ant-design-vue';
import { SearchOutlined } from '@ant-design/icons-vue';

import { assignRolePermissionsApi, getRolePermissionsApi } from '#/api/core/permission';

interface Props {
  open: boolean;
  roleData?: Role;
}

const props = defineProps<Props>();
const emit = defineEmits(['update:open', 'success']);

const confirmLoading = ref(false);
const loading = ref(false);

// 权限列表数据
const permissionList = ref<RolePermissionTreeNode[]>([]);
// 搜索关键词
const searchKeyword = ref('');
// 选中的权限ID
const selectedPermissionIds = ref<number[]>([]);

// 监听弹窗显示状态和角色数据变化
watch(
  () => [props.open, props.roleData] as const,
  async ([open, roleData]) => {
    if (open && roleData?.id) {
      await loadRolePermissions(roleData.id);
    } else {
      // 关闭弹窗时清空搜索
      searchKeyword.value = '';
    }
  },
  { immediate: true },
);

// 加载角色权限列表
async function loadRolePermissions(roleId: number) {
  try {
    loading.value = true;
    const data = await getRolePermissionsApi(roleId);

    permissionList.value = data;

    // 提取已选中的权限ID
    selectedPermissionIds.value = data
      .filter((item) => item.checked)
      .map((item) => item.id);

    console.log('📋 加载角色权限成功:', {
      roleId,
      总数量: data.length,
      已选中: selectedPermissionIds.value.length,
      权限列表: data,
    });
  } catch (error) {
    message.error('加载角色权限失败');
  } finally {
    loading.value = false;
  }
}

// 过滤后的权限列表
const filteredPermissionList = computed(() => {
  if (!searchKeyword.value.trim()) {
    return permissionList.value;
  }

  const keyword = searchKeyword.value.toLowerCase().trim();
  return permissionList.value.filter(
    (item) =>
      item.permissionCode.toLowerCase().includes(keyword) ||
      item.permissionName.toLowerCase().includes(keyword),
  );
});

// 全选/取消全选
const isAllSelected = computed(() => {
  if (filteredPermissionList.value.length === 0) return false;
  return filteredPermissionList.value.every((item) =>
    selectedPermissionIds.value.includes(item.id),
  );
});

const isIndeterminate = computed(() => {
  const selectedCount = filteredPermissionList.value.filter((item) =>
    selectedPermissionIds.value.includes(item.id),
  ).length;
  return selectedCount > 0 && selectedCount < filteredPermissionList.value.length;
});

function handleSelectAll(checked: boolean) {
  if (checked) {
    // 全选：添加当前过滤列表中的所有权限ID
    const currentIds = filteredPermissionList.value.map((item) => item.id);
    selectedPermissionIds.value = [
      ...new Set([...selectedPermissionIds.value, ...currentIds]),
    ];
  } else {
    // 取消全选：移除当前过滤列表中的所有权限ID
    const currentIds = new Set(filteredPermissionList.value.map((item) => item.id));
    selectedPermissionIds.value = selectedPermissionIds.value.filter(
      (id) => !currentIds.has(id),
    );
  }
}

// 单选权限
function handleSelectPermission(permissionId: number, checked: boolean) {
  if (checked) {
    selectedPermissionIds.value.push(permissionId);
  } else {
    selectedPermissionIds.value = selectedPermissionIds.value.filter(
      (id) => id !== permissionId,
    );
  }
}

// 表格列定义
const columns: TableColumnsType = [
  {
    title: '权限编码',
    dataIndex: 'permissionCode',
    key: 'permissionCode',
    width: 200,
  },
  {
    title: '权限名称',
    dataIndex: 'permissionName',
    key: 'permissionName',
    width: 200,
  },
  {
    title: '权限类型',
    dataIndex: 'permissionType',
    key: 'permissionType',
    width: 200,
    align: 'center',
  },
  {
    title: '接口地址',
    dataIndex: 'url',
    key: 'url',
    width: 200,
    ellipsis: true,
  },
  {
    title: '请求方法',
    dataIndex: 'method',
    key: 'method',
    width: 200,
    align: 'center',
  },
  {
    title: '所属菜单',
    dataIndex: 'menuName',
    key: 'menuName',
    width: 200,
    ellipsis: true,
  },
];

// 确定
async function handleOk() {
  if (!props.roleData?.id) return;

  try {
    confirmLoading.value = true;

    console.log('分配权限 - 详细信息:', {
      roleId: props.roleData.id,
      roleName: props.roleData.roleName,
      permissionIdList: selectedPermissionIds.value,
      总数量: selectedPermissionIds.value.length,
    });

    await assignRolePermissionsApi(props.roleData.id, selectedPermissionIds.value);
    message.success('分配权限成功');

    emit('success');
    handleCancel();
  } catch (error) {
    console.error('分配权限失败:', error);
    message.error('分配权限失败');
  } finally {
    confirmLoading.value = false;
  }
}

// 取消
function handleCancel() {
  emit('update:open', false);
  selectedPermissionIds.value = [];
  searchKeyword.value = '';
}
</script>

<template>
  <Modal
    :open="open"
    title="分配权限"
    :confirm-loading="confirmLoading"
    width="1200px"
    @ok="handleOk"
    @cancel="handleCancel"
  >
    <Spin :spinning="loading">
      <!-- 角色信息 -->
      <div class="mb-4 rounded-lg border border-blue-200 bg-gradient-to-r from-blue-50 to-indigo-50 p-3">
        <div class="flex items-center gap-4">
          <div class="flex items-center gap-2">
            <div class="flex h-8 w-8 items-center justify-center rounded-full bg-blue-500 text-white">
              <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 20 20" fill="currentColor">
                <path d="M13 6a3 3 0 11-6 0 3 3 0 016 0zM18 8a2 2 0 11-4 0 2 2 0 014 0zM14 15a4 4 0 00-8 0v3h8v-3zM6 8a2 2 0 11-4 0 2 2 0 014 0zM16 18v-3a5.972 5.972 0 00-.75-2.906A3.005 3.005 0 0119 15v3h-3zM4.75 12.094A5.973 5.973 0 004 15v3H1v-3a3 3 0 013.75-2.906z" />
              </svg>
            </div>
            <div>
              <div class="text-xs text-gray-500">当前角色</div>
              <div class="text-base font-semibold text-gray-900">{{ roleData?.roleName }}</div>
            </div>
          </div>
          <div class="h-8 w-px bg-blue-200"></div>
          <div>
            <div class="text-xs text-gray-500">角色编码</div>
            <div class="font-mono text-sm font-medium text-blue-600">{{ roleData?.roleCode }}</div>
          </div>
        </div>
      </div>

      <!-- 搜索框和全选 -->
      <div class="mb-3 flex items-center gap-3">
        <Input
          v-model:value="searchKeyword"
          placeholder="搜索权限编码或名称..."
          allow-clear
          class="flex-1"
        >
          <template #prefix>
            <SearchOutlined />
          </template>
        </Input>
        <Checkbox
          :checked="isAllSelected"
          :indeterminate="isIndeterminate"
          @change="(e: any) => handleSelectAll(e.target.checked)"
        >
          全选
        </Checkbox>
      </div>

      <!-- 统计信息 -->
      <div class="mb-3 text-sm text-gray-500">
        <span v-if="searchKeyword">
          找到 {{ filteredPermissionList.length }} 个匹配项，已选中 {{ selectedPermissionIds.length }} 个
        </span>
        <span v-else>
          共 {{ permissionList.length }} 个权限，已选中 {{ selectedPermissionIds.length }} 个
        </span>
      </div>

      <!-- 权限列表 -->
      <div class="rounded border border-gray-200">
        <Table
          :columns="columns"
          :data-source="filteredPermissionList"
          :pagination="false"
          :scroll="{ y: 400 }"
          :row-key="(record: RolePermissionTreeNode) => record.id"
          size="small"
        >
          <template #bodyCell="{ column, record }">
            <template v-if="column.key === 'permissionCode'">
              <Checkbox
                :checked="selectedPermissionIds.includes(record.id)"
                @change="(e: any) => handleSelectPermission(record.id, e.target.checked)"
              >
                <span class="font-mono text-xs">{{ record.permissionCode }}</span>
              </Checkbox>
            </template>
            <template v-else-if="column.key === 'permissionType'">
              <span
                v-if="record.permissionType === 1"
                class="inline-flex items-center rounded-full bg-blue-100 px-2.5 py-0.5 text-xs font-medium text-blue-800"
              >
                接口权限
              </span>
              <span
                v-else
                class="inline-flex items-center rounded-full bg-green-100 px-2.5 py-0.5 text-xs font-medium text-green-800"
              >
                按钮权限
              </span>
            </template>
            <template v-else-if="column.key === 'url'">
              <span v-if="record.url" class="text-xs text-gray-600" :title="record.url">
                {{ record.url }}
              </span>
              <span v-else class="text-xs text-gray-400">-</span>
            </template>
            <template v-else-if="column.key === 'method'">
              <span
                v-if="record.method"
                class="inline-flex items-center rounded px-2 py-0.5 text-xs font-medium"
                :class="{
                  'bg-green-100 text-green-800': record.method === 'GET',
                  'bg-blue-100 text-blue-800': record.method === 'POST',
                  'bg-orange-100 text-orange-800': record.method === 'PUT',
                  'bg-red-100 text-red-800': record.method === 'DELETE',
                  'bg-purple-100 text-purple-800': !['GET', 'POST', 'PUT', 'DELETE'].includes(record.method),
                }"
              >
                {{ record.method }}
              </span>
              <span v-else class="text-xs text-gray-400">-</span>
            </template>
            <template v-else-if="column.key === 'menuName'">
              <span v-if="record.menuName" class="text-xs" :title="record.menuName">
                {{ record.menuName }}
              </span>
              <span v-else class="text-xs text-gray-400">-</span>
            </template>
          </template>
        </Table>
      </div>
    </Spin>
  </Modal>
</template>

<style scoped lang="scss">
:deep(.ant-table-body) {
  &::-webkit-scrollbar {
    width: 6px;
  }

  &::-webkit-scrollbar-track {
    background: #f1f1f1;
    border-radius: 3px;
  }

  &::-webkit-scrollbar-thumb {
    background: #c1c1c1;
    border-radius: 3px;

    &:hover {
      background: #a8a8a8;
    }
  }
}
</style>

